﻿using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Mayn.Video
{
    public class BaseDal<T> where T : class, new()
    {
        private SqlSugarClient db = DbClient.Db;

        /// <summary>
        /// 添加单个实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Add(T entity) => db.Insertable<T>(entity).ExecuteCommand();

        /// <summary>
        /// 添加返回自增ID
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int AddReturnId(T entity) => db.Insertable<T>(entity).ExecuteReturnIdentity();

        /// <summary>
        /// 添加返回实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T AddReturnEntity(T entity) => db.Insertable<T>(entity).ExecuteReturnEntity();

        /// <summary>
        /// 批量添加实体
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public int Add(IList<T> entities) => 0;


        public int Count(Expression<Func<T, bool>> where = null) => db.Queryable<T>().Count(where);

        /// <summary>
        /// 根据实体删除，需要配置主键 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Delete(T entity) => db.Deleteable<T>(entity).ExecuteCommand();

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int Delete(object id) => db.Deleteable<T>().In(id).ExecuteCommand();

        /// <summary>
        /// 根据主键删除批量删除
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public int Delete(IList<Object> idList) => db.Deleteable<T>().In(idList).ExecuteCommand();

        /// <summary>
        /// 根据条件删除
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public int Delete(Expression<Func<T, bool>> where) => db.Deleteable<T>().Where(where).ExecuteCommand();

        /// <summary>
        /// 根据id查询单个实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T Get(int id) => db.Queryable<T>().InSingle(id);

        /// <summary>
        /// 根据条件查询单个实体
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public T Get(Expression<Func<T, bool>> where) => db.Queryable<T>().First(where);

        /// <summary>
        /// 查询所有数据（慎用）
        /// </summary>
        /// <returns></returns>
        public IList<T> GetAll() => db.Queryable<T>().ToList();

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public IList<T> GetAll(Expression<Func<T, bool>> where) => db.Queryable<T>().Where(where).ToList();

        /// <summary>
        /// 分页查询（返回总数）
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="where"></param>
        /// <param name="orderBy"></param>
        /// <param name="desc"></param>
        /// <param name="pageNo"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public IList<T> GetList<TKey>(Expression<Func<T, bool>> where, string orderBy, bool desc, int pageNo, int pageSize, out int count)
        {
            count = db.Queryable<T>().Count(where);
            return db.Queryable<T>().Where(where).Skip((pageNo - 1) * pageSize).Take(pageSize).OrderBy(orderBy).ToList();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="where"></param>
        /// <param name="orderBy"></param>
        /// <param name="desc"></param>
        /// <param name="pageNo"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IList<T> GetList<TKey>(Expression<Func<T, bool>> where, string orderBy, bool desc, int pageNo, int pageSize) =>
            db.Queryable<T>().Where(where).Skip((pageNo - 1) * pageSize).Take(pageSize).OrderBy(orderBy).ToList();

        /// <summary>
        /// 查询所有数据（慎用）
        /// </summary>
        /// <returns></returns>
        public DataTable GetAllTable() => db.Queryable<T>().ToDataTable();

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public DataTable GetAllTable(Expression<Func<T, bool>> where) => db.Queryable<T>().Where(where).ToDataTable();

        /// <summary>
        /// 分页查询（返回总数）
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="where"></param>
        /// <param name="orderBy"></param>
        /// <param name="desc"></param>
        /// <param name="pageNo"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public DataTable GetDataTable<TKey>(Expression<Func<T, bool>> where, string orderBy, bool desc, int pageNo, int pageSize, out int count)
        {
            count = db.Queryable<T>().Count(where);
            return db.Queryable<T>().Where(where).Skip((pageNo - 1) * pageSize).Take(pageSize).OrderBy(orderBy).ToDataTable();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="where"></param>
        /// <param name="orderBy"></param>
        /// <param name="desc"></param>
        /// <param name="pageNo"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public DataTable GetDataTable<TKey>(Expression<Func<T, bool>> where, string orderBy, bool desc, int pageNo, int pageSize) =>
            db.Queryable<T>().Where(where).Skip((pageNo - 1) * pageSize).Take(pageSize).OrderBy(orderBy).ToDataTable();

        /// <summary>
        /// 查询是否存在
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public bool IsExist(Expression<Func<T, bool>> where) => this.Count(where) > 0;

        /// <summary>
        /// 更新单个实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(T entity) => db.Updateable<T>(entity).ExecuteCommand();

        /// <summary>
        /// 更新多个实体
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public int Update(IList<T> entities) => db.Updateable<T>(entities).ExecuteCommand();
    }
}
